package com.example.androidstudy.ui.demo.bezier

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.customview.widget.ViewDragHelper
import com.example.androidstudy.extend.logE

class DragableView @JvmOverloads constructor(
    context: Context,
    val attrs: AttributeSet? = null,
    val defStyleAttr: Int = 0,
    val defStyleRes: Int = 0

) : androidx.appcompat.widget.AppCompatImageView(context, attrs, defStyleAttr) {
    var positionChanged: (left: Int, top: Int) -> Unit = { x, y ->
        "$x $y".logE("DragableView")
    }
    lateinit var viewDragHelper: ViewDragHelper
    val dragCallBack = object : ViewDragHelper.Callback() {
        override fun tryCaptureView(child: View, pointerId: Int): Boolean {

            return this@DragableView == child
        }

        override fun onViewCaptured(capturedChild: View, activePointerId: Int) {
        }

        override fun getViewHorizontalDragRange(child: View): Int {
            return (parent as ViewGroup).width
        }

        override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {
            return left
        }

        override fun getViewVerticalDragRange(child: View): Int {
            return (parent as ViewGroup).height
        }

        override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int {
            return top
        }

        override fun onViewDragStateChanged(state: Int) {
            when (state) {
                ViewDragHelper.STATE_SETTLING -> {
                    this@DragableView.imageTintList = ColorStateList.valueOf(Color.GREEN)
                }
                ViewDragHelper.STATE_IDLE -> {
                    this@DragableView.imageTintList = ColorStateList.valueOf(Color.RED)
                }
                ViewDragHelper.STATE_DRAGGING -> {
                    this@DragableView.imageTintList = ColorStateList.valueOf(Color.CYAN)
                }
            }
        }

        override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
            val dragableView = this@DragableView
            viewDragHelper.flingCapturedView(
                10, 10, getViewHorizontalDragRange(releasedChild)-dragableView.width,
                getViewVerticalDragRange(releasedChild)-dragableView.height
            )

            ViewCompat.postOnAnimation(dragableView, SettlingRunnable())
            "$releasedChild :onViewReleased $xvel $yvel".logE()
        }

        inner class SettlingRunnable : Runnable {
            override fun run() {
                if (viewDragHelper.viewDragState == ViewDragHelper.STATE_SETTLING && viewDragHelper.continueSettling(
                        true
                    )
                ) {
                    ViewCompat.postOnAnimation(this@DragableView, this)
                }
            }
        }

        override fun onViewPositionChanged(
            changedView: View,
            left: Int,
            top: Int,
            dx: Int,
            dy: Int
        ) {
            val viewGroup = parent as ViewGroup
            positionChanged(
                (left + width / 2) * 100 / viewGroup.width,
                (top + height / 2) * 100 / viewGroup.height
            )
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!::viewDragHelper.isInitialized) {
            val viewGroup = parent as ViewGroup
            viewDragHelper = ViewDragHelper.create(viewGroup, dragCallBack)
            viewGroup.setOnTouchListener { v, event ->
                viewDragHelper.processTouchEvent(event)
                return@setOnTouchListener (MotionEvent.ACTION_DOWN == event.getActionMasked()).apply {
                    if (this) {
                        "down".logE()
                    }
                }
            }
        }
        return false
    }

}